#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>


#define  LEFT   30000000
#define  RIGHT  30000200
#define  THRNUM  4

int num = 0;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

static void *thr_prime(void *p) {
	int _num, j, mark;
	while (1) {
		pthread_mutex_lock(&mut);
		while (num == 0) {
			pthread_mutex_unlock(&mut);
			sched_yield();
			pthread_mutex_lock(&mut);
		}
		if (num < 0) {
			pthread_mutex_unlock(&mut);
			break;
		}
		_num = num;
		num = 0;
		pthread_mutex_unlock(&mut);
		mark = 1;
		for (j = 2; j < _num/ 2; j++) {
 			if (_num% j == 0) {
 				mark = 0;
		 	 	break;
			}
		}
		if (mark) {
			printf("[%d] %d is a primer\n",(int)p, _num);
		}
	}
	pthread_exit(NULL);
}


int main() {
	int i = 0;
	int err;
	pthread_t tid[THRNUM];
	for (i = 0; i <= THRNUM; i++) {
		err = pthread_create(tid + i, NULL, thr_prime, (void*)i);
		if (err) {
			fprintf(stderr, " pthread_create():%s", strerror(err));
			exit(1);
		}
	}
	for (i = LEFT; i < RIGHT; i++) {
		pthread_mutex_lock(&mut);
		while (num != 0) {
			pthread_mutex_unlock(&mut);
			sched_yield();
			pthread_mutex_lock(&mut);
		}	
			num = i;
		pthread_mutex_unlock(&mut);
	}
	pthread_mutex_lock(&mut);
	while (num != 0) {
		pthread_mutex_unlock(&mut);
		sched_yield();
		pthread_mutex_lock(&mut);
	}
	num = -1;
	pthread_mutex_unlock(&mut);
	for (i = 0; i <= THRNUM; i++) {
		pthread_join(tid[i], NULL);
	}
	pthread_mutex_destroy(&mut);
	exit(0);
}
